using AduSkin.Controls.Data;
using AduSkin.Utility.Element;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;


namespace AduSkin.Controls.Metro
{
   [TemplatePart(Name = ElementContent, Type = typeof(FrameworkElement))]
   [TemplatePart(Name = ElementPanel, Type = typeof(Panel))]
   public class AduRunningBlock : ContentControl
   {
      public AduRunningBlock()
      {
         
      }

      static AduRunningBlock()
      {
         ElementBase.DefaultStyle<AduRunningBlock>(DefaultStyleKeyProperty);
      }
      private const string ElementContent = "PART_ContentElement";

      private const string ElementPanel = "PART_Panel";

      protected Storyboard _storyboard;

      private FrameworkElement _elementContent;

      private FrameworkElement _elementPanel;

      public override void OnApplyTemplate()
      {
         base.OnApplyTemplate();

         _elementContent = GetTemplateChild(ElementContent) as FrameworkElement;
         _elementPanel = GetTemplateChild(ElementPanel) as Panel;
      }

      public static readonly DependencyProperty RunawayProperty = DependencyProperty.Register(
          "Runaway", typeof(bool), typeof(AduRunningBlock), new FrameworkPropertyMetadata(ValueBoxes.TrueBox, FrameworkPropertyMetadataOptions.AffectsRender));

      public bool Runaway
      {
         get => (bool)GetValue(RunawayProperty);
         set => SetValue(RunawayProperty, value);
      }

      public static readonly DependencyProperty AutoRunProperty = DependencyProperty.Register(
          "AutoRun", typeof(bool), typeof(AduRunningBlock), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender));

      public bool AutoRun
      {
         get => (bool)GetValue(AutoRunProperty);
         set => SetValue(AutoRunProperty, value);
      }

      public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
          "Orientation", typeof(Orientation), typeof(AduRunningBlock), new FrameworkPropertyMetadata(default(Orientation), FrameworkPropertyMetadataOptions.AffectsRender));

      public Orientation Orientation
      {
         get => (Orientation)GetValue(OrientationProperty);
         set => SetValue(OrientationProperty, value);
      }

      public static readonly DependencyProperty DurationProperty = DependencyProperty.Register(
          "Duration", typeof(Duration), typeof(AduRunningBlock), new FrameworkPropertyMetadata(new Duration(TimeSpan.FromSeconds(5)), FrameworkPropertyMetadataOptions.AffectsRender));

      public Duration Duration
      {
         get => (Duration)GetValue(DurationProperty);
         set => SetValue(DurationProperty, value);
      }

      public static readonly DependencyProperty IsRunningProperty = DependencyProperty.Register(
          "IsRunning", typeof(bool), typeof(AduRunningBlock), new PropertyMetadata(ValueBoxes.TrueBox, (o, args) =>
          {
             var ctl = (AduRunningBlock)o;
             var v = (bool)args.NewValue;
             if (v)
             {
                ctl._storyboard?.Resume();
             }
             else
             {
                ctl._storyboard?.Pause();
             }
          }));

      public bool IsRunning
      {
         get => (bool)GetValue(IsRunningProperty);
         set => SetValue(IsRunningProperty, value);
      }

      public static readonly DependencyProperty AutoReverseProperty = DependencyProperty.Register(
          "AutoReverse", typeof(bool), typeof(AduRunningBlock), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsRender));

      public bool AutoReverse
      {
         get => (bool)GetValue(AutoReverseProperty);
         set => SetValue(AutoReverseProperty, value);
      }

      private void UpdateContent()
      {
         if (_elementContent == null || _elementPanel == null) return;

         _storyboard?.Stop();

         _elementPanel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
         _elementPanel.Width = _elementPanel.DesiredSize.Width;
         _elementPanel.Height = _elementPanel.DesiredSize.Height;

         double from;
         double to;
         PropertyPath propertyPath;

         if (Orientation == Orientation.Horizontal)
         {
            if (AutoRun && _elementPanel.Width < ActualWidth)
            {
               return;
            }

            if (Runaway)
            {
               from = -_elementPanel.Width;
               to = ActualWidth;
            }
            else
            {
               from = 0;
               to = ActualWidth - _elementPanel.Width;
               SetCurrentValue(AutoReverseProperty, ValueBoxes.TrueBox);
            }
            propertyPath = new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)");
         }
         else
         {
            if (AutoRun && _elementPanel.Height < ActualHeight)
            {
               return;
            }

            if (Runaway)
            {
               from = -_elementPanel.Height;
               to = ActualHeight;
            }
            else
            {
               from = 0;
               to = ActualHeight - _elementPanel.Height;
               SetCurrentValue(AutoReverseProperty, ValueBoxes.TrueBox);
            }
            propertyPath = new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)");
         }

         var animation = new DoubleAnimation(from, to, Duration)
         {
            RepeatBehavior = RepeatBehavior.Forever,
            AutoReverse = AutoReverse
         };
         Storyboard.SetTargetProperty(animation, propertyPath);
         Storyboard.SetTarget(animation, _elementContent);

         _storyboard = new Storyboard();
         _storyboard.Children.Add(animation);
         _storyboard.Begin();
      }

      protected override void OnRender(DrawingContext drawingContext)
      {
         base.OnRender(drawingContext);
         UpdateContent();
      }
   }
}
